/**
 * Copyright (C) 2013 Daniel Gee.
 * See LICENSE.txt for more details.
 */
package com.rl.gui;

import com.rl.dungeon.Location;

/**
 * Interface for things that want to be displayed in the GUI. Locations are mapped into Appearances
 * via the {@link #getAppearanceAt(Location)} method.
 * 
 * @author Daniel Gee
 */
public interface AppearanceMap
{
	/**
	 * Gets the Appearance of whatever should be shown to be at the location specified. Only a
	 * single Appearance can be displayed at a given Location at a time, so the implementing class
	 * must decide what Appearance takes precedence if more than one Appearance is possible at a
	 * given location. Generally the order of preference when more than one thing is at the same
	 * location is Creatures, Items, Traps, Terrain, but this is not at all a requirement. This
	 * method must never return a <tt>null</tt> value. If a location requested is outside of the
	 * bounds of the playspace, use the appearance of <tt>DungeonTerrain.Void</tt> (or some other
	 * "blank" default) as the return value.
	 * 
	 * @param location
	 *            the location in question.
	 * @return the Appearance at the Location specified.
	 */
	public Appearance getAppearanceAt(Location location);

	/**
	 * Should compute and return the location that displaying should start with. This allows for a
	 * scrollable display in cases where the display isn't as big as the AppearanceMap being
	 * displayed. The display will start at the location provided, moving <tt>displayWidth</tt>
	 * units along the X-axis and <tt>displayHeight</tt> along the Y-axis, and draw everything in
	 * the resulting rectangle. The Z-axis remains consistent during a single drawing sequence.
	 * 
	 * <p>
	 * For example:<br />
	 * <tt>return getPlayerLocation().translate(-displayWidth/2,-displayHeigh/2);</tt><br />
	 * could be used to simply keep the player at the center of the display at all times (similar to
	 * Crawl).
	 * </p>
	 * <p>
	 * If the displayWidth and displayHeight are both equal to or greater than that of the dungeon,
	 * then something like:<br/>
	 * <tt>return Location.of(0,0,getPlayerLocation().z);</tt><br />
	 * could be used to display the player's current level with the dungeon's upper left corner
	 * aligned with the upper left of the display (similar to NetHack).
	 * </p>
	 * 
	 * @param displayWidth
	 *            how many cells wide the target display will be.
	 * @param displayHeight
	 *            how many cells tall the target display will be.
	 * @return the Location that the displaying class should scroll to before beginning the display.
	 */
	public Location getDisplayStartLocation(int displayWidth, int displayHeight);
}
